/**
 * 表单的View定义，表单使用的相关功能，View路径：module/component/views/FormView
 * @class ngc.component.view.FormView
 * @author gong.xiangfei
 */
define(["module/component/views/CommonUIView",  "text!module/component/templates/FormView.html"], function(CommonView, formTemplate) {	
	
	var FormView = CommonView.extend({
		template: ngc.compile(formTemplate),
		serialize:function(){
			if (!this.options.config.id) {
				this._obj_id = this.getOptionConfig().id = ngc.getUUID();
			}
			
			if(!ngc.isNumber(this.getOptionConfig().column)){
				this.getOptionConfig().column = 3;
			}
			if(this.getOptionConfig().notSuit){
				this.getOptionConfig()._lg_c = 12/this.getOptionConfig().column;
				this.getOptionConfig()._md_c = 12/this.getOptionConfig().column;
				this.getOptionConfig()._sm_c = 12/this.getOptionConfig().column;
			}else{
				this.getOptionConfig()._lg_c = 12/(this.getOptionConfig().column+1);
				this.getOptionConfig()._md_c = 12/this.getOptionConfig().column;
				this.getOptionConfig()._sm_c = (this.getOptionConfig()._md_c==12?this.getOptionConfig()._md_c:(12/(this.getOptionConfig().column-1)));
			}
			
			return this.getOptionConfig();
		},
		
		afterRender: function() {

			this._idIndexMatch = {};

			$('#' + this._obj_id).form();
			
			this._initForm();

		},
		
		
		_getInputObject: function(id) {
			return this.$('#' + id);
		},

		_getElementConfigByIndex: function(index) {
			return this.getOptionConfig().elements[index];
		},

		_getElementConfigById: function(id) {
			return this._getElementConfigByIndex(this._idIndexMatch[id]);
		},

		/**
		 * 设置整个表单的值
		 * @method setValues
		 * @param {Object} values Json对象的Key和表单中每个输入框ID对应
		 */
		setValues: function(values) {
			this.getComponentObject().form('value', values);
		},
		
		/**
		 * 校验表单
		 * @method valid
		 * @return {Boolean} true/false
		 */
		valid:function(){
			return this.getComponentObject().isValid();
		},
		
		/**
		 * 清除表单校验结果
		 * @method validCleanUp
		 */
		validCleanUp:function(){
			this.getComponentObject().validator("cleanUp");
		},
		
		/**
		 * 获取表单所有输入框的值
		 * @method getValues
		 * @return {Object} 
		 */
		getValues: function() {
			return this.getComponentObject().form('value');
		},

		/**
		 * @method 初始化下拉框的值
		 * @param {String} id:输入框控件唯一ID
		 * @param {Array|Function} items:初始化的下拉框数组或者函数，如果是函数，则要保证此函数的返回值是数组
		 */
		initDropItem: function(iid, items) {
			var _dropItems = items
			if (ngc.isFunction(items)) {
				_dropItems = items.call(this, this._getElementConfigById(iid));
			}
			// 设置值
			if (ngc.isArray(_dropItems)) {
				var _cfg = this._getElementConfigById(iid);
				switch (_cfg.type) {
				case 'select':
					this._getInputObject(_cfg.id).combobox({
						dataSource: _dropItems
					});
					break;
				case 'multiselect':
					this._getInputObject(_cfg.id).multiselect('option', {
						dataTextField: _cfg.dataTextField,
						dataValueField: _cfg.dataValueField,
						dataSource: _dropItems
					});
					break;

				}
			}
		},
		
		/**
		 * 重置表单
		 * @method reset
		 */
		reset:function(){
			this.getComponentObject().form('clear');
		},

		_addIndexIdMatch: function(id, index) {
			this._idIndexMatch[id] = index;
		},

		/**
		 * @method 获取输入框的值
		 * @param id:输入框的ID
		 * @return {Object} 返回结果为{value:""}或者多选情况下的{value:["",""]}
		 */
		getValue: function(id) {
			var cfg = this._getElementConfigById(id);
			var $input = this._getInputObject(id);
			switch (cfg.type) {
			case 'multiselect':
				return {
					value: $input.multiselect('value')
				};
			case 'select':
				return {
					value: $input.combobox('value')
				};
			case 'autocomplete':
				return {
					value: $input.val()
				};
			case 'searchbar':				
				return {value:$input.searchbar('value'),condition:$input.searchbar('filterField')}
			default:
				return {
					value: $input.val()
				};
			}
		},
		
		
		/**
		 * @method 获取输入框的值和文本
		 * @param id:输入框的ID
		 * @return {Object} 返回结果为{value:""}或者多选情况下的{value:["",""]}
		 */
		getValueText: function(id) {
			var cfg = this._getElementConfigById(id);
			var $input = this._getInputObject(id);
			switch (cfg.type) {
			case 'multiselect':
				return {
					value: $input.multiselect('value')
				};
			case 'select':
				if(cfg.editable){
					return {
						value: $input.combobox('value'),
						text: this.$('#top_node_'+cfg.id).find('input.form-control').val()
					};
				}else{
					return {
						value: $input.combobox('value'),
						text: this.$('#top_node_'+cfg.id).find('span.combobox-text').html()
					};
				}
			case 'autocomplete':
				return {
					value: $input.val(),
					text: this._getInputObject(id+"_text").val()
				};
			case 'searchbar':				
				return {value:$input.searchbar('value'),text: $input.searchbar('value'),condition:$input.searchbar('filterField')}
			default:
				return {
					value: $input.val()
				};
			}
		},
		
		/**
		 * 隐藏输入框
		 * @method hide
		 * @param {String} [id]：输入框的唯一标识ID,当不输入id时候隐藏整个表单
		 */
		hide:function(id){
			if(!id){
				var that = this;
				$.each(this.getOptionConfig().elements,function(){
					that.$("#top_node_"+this.id).hide();
				})
				return;
			}
			this.$("#top_node_"+id).hide();
		},
		
		/**
		 * 隐藏整个表单
		 * @method hideForm
		 * 
		 */
		hideForm:function(){
			this.$("#form_elements_"+this.getComponentId()).hide();
		},
		
		
		/**
		 * 显示输入框
		 * @method show
		 * @param {String} [id]：输入框的唯一标识ID,当不传入时，隐藏所有表单元素
		 */
		show:function(id){
			if(!id){
				var that = this;
				$.each(this.getOptionConfig().elements,function(){
					that.$("#top_node_"+this.id).show();
				})
				return;
			}
			 this.$("#top_node_"+id).show();
		},
		
		/**
		 * 显示整个表单
		 * @method showForm
		 * @param {String} [id]：输入框的唯一标识ID,当不传入时，隐藏所有表单元素
		 */
		showForm:function(id){
			this.$("#form_elements_"+this.getComponentId()).show();
		},

		/**
		 * 禁用输入框控件
		 * @method disable
		 * @param {String} id：输入框的唯一标识ID
		 */
		disable: function(id) {
			if(!id){
				this.disableForm();
				return;
			}
				
			var cfg = this._getElementConfigById(id);
			var $input = this._getInputObject(id);
			switch (cfg.type) {
			case 'multiselect':
				$input.multiselect('disable');
				break;
			case 'select':
				$input.combobox('disable');
				break;
			case 'autocomplete':
				$input = this._getInputObject(id+"_text");
				$input.attr("disabled", true);
				break;
			default:
				$input.attr("disabled", true);
			}
		},
		/**
		 * 禁用表单
		 * @method disableForm
		 * 
		 */		
		disableForm: function() {
			this.getComponentObject().form('disable');
		},
		/**
		 * 启用表单
		 * @method enableForm
		 * 
		 */		
		enableForm: function() {
			this.getComponentObject().form('enable');
		},
		/**
		 * 启用输入框控件
		 * @method enable
		 * @param {String} id：需要启用的输入框唯一标识ID
		 */
		enable: function(id) {
			if(!id){
				this.enableForm();
				return;
			}
				
			var cfg = this._getElementConfigById(id);
			var $input = this._getInputObject(id);
			switch (cfg.type) {
			case 'multiselect':
				$input.multiselect('enable');
				break;
			case 'select':
				$input.combobox('enable');
				break;
			case 'autocomplete':
				$input = this._getInputObject(id+"_text");
				$input.attr("disabled", false);
				break;	
			default:
				$input.attr("disabled", false);
			}
		},

		/**
		 * 设置form输入框的值
		 * @method initValue
		 * @param {String} id:输入框的ID
		 * @param {Object} value:输入框的初始值，单值采用{value:'值'}，多指采用{value:['值1','值2']}            
		 */
		initValue: function(id, value) {
			var old = this.getValue(id);
			
			if(old.value!=value){
				var cfg = this._getElementConfigById(id);
				var $input = this._getInputObject(id);
				if (!value || !value.value) value.value = '';
				switch (cfg.type) {
				case 'multiselect':
					$input.multiselect('value', value.value);
					break;
				case 'select':
					$input.combobox('value', value.value);
					break;
				case 'autocomplete':
					$input.val(value.value);
					this._getInputObject(id+"_text").val(value.text);
					this._getInputObject(id).change();
					break;
				case 'switch':
					if(value.value==1){
						value.value = true;
					}
					if(value.value==0){
						value.value = false;
					}
					this._getInputObject(id).switchbutton('option','state',value.value);
					break;
				case 'searchbar':				
					this._getInputObject(id).searchbar('value',value.value);
					if(value.condition){
						this._getInputObject(id).searchbar('filterField',value.condition);
					}
					break;
				default:
					$input.val(value.value);
					this._getInputObject(id).change();
				}
				
			}
			
		},
		
//		_getDropItemDynValue: function(enumValue,success){
//			return ngc.callServerFunction(this.getOptionConfig().enum?this.getOptionConfig().enum.service:'com.ztesoft.res.dynconfig.common.inf.CommonConstQueryServiceInf', 
//					this.getOptionConfig().enum?this.getOptionConfig().enum.method:'queryFrameworkConfDictByKeyword', 
//					enumValue, 
//					success?success:$.noop);
//		},
		
		_getDropItemDynValue: function(enumValue,success){
			if(global.enumData[enumValue] == undefined){
				var _data = ngc.callServerFunction("com.datax.web.service.CommonService","getDropItem", enumValue, success);
				global.enumData[enumValue] = _data;
				return _data;
			}
			return global.enumData[enumValue];
		},
		
//		_getDropItemDynValue: function(enumValue,success){
//			return ngc.callServerFunction("com.ztesoft.hostapp.inf.CommonInf","getDropItem", enumValue, success);
//		},

		//初始化表格
		_initForm: function() {
			var that = this;

			$.each(
				this.getOptionConfig().elements, function(i) {
					that._addIndexIdMatch(this.id, i);
	
					// 设置下拉框列表的初始化值
					// 对于动态初始化下拉框的值由于异步操作，采用代码同步的方式控制
					if (this.type == 'select' || this.type == 'multiselect') {
						if (ngc.isFunction(this.options)) {
							this.options = this.options.call(that, this);
						} else if(!this.options&&this.enumCode){
							$.when(that._getDropItemDynValue(this.enumCode)).then(function(data){
								this.options = data.data;
								that._inputElementInit(this);
							}.bind(this));
							return;
						}	
					}
					
					that._inputElementInit(this);
					
			});
			// Render After 事件
			this.trigger("viewRenderAfter");
			this.setInitFlag(true);
		},
		
		//初始化每个输入框元素
		_inputElementInit:function(cfg){
			var that = this;
			switch (cfg.type) {
				case 'text':
				case 'password':					
					this._getInputObject(
							cfg.id).clearinput();
					break;
				case 'date':
					var opts = {
						format: cfg.format ? cfg.format : 'yyyy/mm/dd hh:ii:ss'
					};
					if (cfg.viewType) {
						opts.viewType = cfg.viewType;
					}
					this._getInputObject(
							cfg.id).datetimepicker(opts);
					break;
				case 'searchbar':
					var $search = this._getInputObject(
							cfg.id).searchbar(cfg);
					if(ngc.isFunction(cfg.search)){
						this.$("#top_node_"+cfg.id).find("input").keydown(function(e){
							 if(e.which == 13){
								 cfg.search.call(that,$search.searchbar('value'),$search.searchbar('filterField'));
							 }
						});
					}
					
					if(cfg.btn){
						this.$("#"+cfg.id).children("span").eq(0).appendTo(this.$("#"+cfg.id));
					}
					break;
				case 'select':
					cfg.dataTextField = cfg.dataTextField ? cfg.dataTextField : 'NAME';
					cfg.dataValueField = cfg.dataValueField ? cfg.dataValueField : 'VALUE';
					cfg.editable = cfg.editable ? true : false;
					
					if(!cfg.options)cfg.options = [];
					
					if (ngc.isArray(cfg.options)) {
						this._getInputObject(
								cfg.id).combobox({
									placeholder: cfg.placeholder||('--请选择' + cfg.label + '--'),
									dataTextField: cfg.dataTextField,
									editable: cfg.editable,
									dataValueField: cfg.dataValueField,
									dataSource: cfg.options
								});
					}
					break;
				case 'autocomplete':
					var that = this;
					var _acfg = {
							minLength : cfg.minLength?cfg.minLength:2,
							source : ngc.isFunction(cfg.source)?cfg.source.bind(that):cfg.source,
							select: cfg.select?cfg.select:function (e, ui) {
								$(this).val(ui.item[cfg.dataTextField]);
								that._getInputObject(cfg.id).val(ui.item[cfg.dataValueField||cfg.dataTextField]);
								that._getInputObject(cfg.id).change();
								return false;
							},
					        itemRenderer: cfg.itemRenderer?cfg.itemRenderer:function (item) {
					            return item[cfg.dataTextField];
					        }
					}

					this._getInputObject(
							cfg.id+"_text").autocomplete(_acfg);	
					
					this._getInputObject(cfg.id)
						.change(function(e) {
								var _id = cfg.id;
								if(!$(this).val()){
									that._getInputObject(_id+"_text").val("");
								}
						});
					
					this._getInputObject(cfg.id+"_text")
						.bind('input propertychange',function(e) {
								var _id = cfg.id;
								if(that._getInputObject(_id).val()!=null
											&&that._getInputObject(_id).val()!=''){
									that._getInputObject(_id).val("");
									that._getInputObject(_id).change();
								}
								
						});
					break;
				case 'spinner':
					cfg = $.extend({
						min: 0
					},cfg);
					this._getInputObject(
					cfg.id).spinner(cfg)					
					break;
				case 'switch':
					this._getInputObject(
					cfg.id).switchbutton(cfg);										
					break;
				case 'multiselect':
					var $select = this._getInputObject(
					cfg.id).multiselect({
						createItem: function(
						e, item) {
							console.log('new item created:', item);
						}
					});
	
					cfg.dataTextField = cfg.dataTextField ? cfg.dataTextField : 'NAME';
					cfg.dataValueField = cfg.dataValueField ? cfg.dataValueField : 'VALUE';
					if (ngc.isArray(cfg.options)) {
						$select.multiselect('option', {
							dataTextField: cfg.dataTextField,
							dataValueField: cfg.dataValueField,
							dataSource: cfg.options
						});
					} 
					
					
					break;
				default:
					
					break;				
			}
			if(cfg.btnClick&&ngc.isFunction(cfg.btnClick)){
				that.$("#"+cfg.id+"_click_btn").click(function(){
					cfg.btnClick.call(that,that.getValue(cfg.id));
				});
			}
			//设置默认值
			if (cfg.defaultValue) {
				this.initValue(
				cfg.id, cfg.defaultValue);
			}
			if(cfg.disable){
				this.disable(cfg.id);
			}
			//分发绑定输入框改变事件
			this._dispatchChangeEvent(cfg);
	 },

	/**
	 * @event inputChange 输入框改变的事件
	 * @param {String} id 当前产生事件的控件ID
	 * @param {Event} e 事件源
	 */
	 
	 	/**
		 * @event viewRenderAfter Form视图初始化之后事件
		 */	 
	 
	 
	/**
	 * 各种输入表单元素的值改变事件分发
	 */
	_dispatchChangeEvent:function(cfg){
		switch (cfg.type) {
		case 'multiselect':
			this._getInputObject(cfg.id).on('multiselect:change', function(e) {
				this._handlerChangeEvent(cfg,e);
			}.bind(this))
			break;
		case 'select':	
			this._getInputObject(cfg.id).on('combobox:change', function(e) {
				this._handlerChangeEvent(cfg,e);
				
			}.bind(this));
			
			this._getInputObject(cfg.id).on('combobox:open', function(e) {
				this.trigger("dropItemDisplay", cfg.id, e);
				
			}.bind(this))
			
		case 'autocomplete':	
			this._getInputObject(
					cfg.id).change(function(e) {
						this._handlerChangeEvent(cfg,e);
					}.bind(this));
			
			break;
			
			default:
				this._getInputObject(
						cfg.id).bind('input propertychange', function(e) {
							this._handlerChangeEvent(cfg,e);
						}.bind(this));
		}
		
		this.trigger("inputElementInitAfter",cfg);
	},
	
	_handlerChangeEvent:function(cfg, e){
		this.trigger("inputChange", cfg.id, e);
		if(this.getOptionConfig().callback){
			if(this.getOptionConfig().callback.onChange){
				this.getOptionConfig().callback.onChange.call(this,cfg.id,e);
			}
		}
	}
	
	
	
	
	
	});
	return FormView; 
	
	/**
	 * @cfg {Object} config 初始化表单配置
	 * @cfg {Array} config.elements 表单配置项数组
	 * @cfg {Array} config.callback 表单事件，支持的时间类型为onChange，不断扩充中。。。参数： @param {String} id 当前产生事件的控件ID @param {Event} e 事件源
	 * @cfg {String} config.elements.id 表单元素唯一标识，用于表单中各种输入框获取与操作
	 * @cfg {String} config.elements.type 输入框控件类型，目前支持:text、hidden、select、autocomplete、password、date、multiselect、spinner、switch、textarea、link
	 * @cfg {String} config.elements.btn 输入框后面按钮，此处为按钮的图标，当type为text、select类型支持该图标，图标采用"glyphicon-cog"形式，具体图标参见http://v3.bootcss.com/components/
	 * @cfg {Function} config.elements.btnClick 当btn设置之后的按钮点击事件回调函数，入参为当前输入框的值
	 * @cfg {Object} config.elements.defaultValue 默认值，可选
	 * @cfg {String} config.elements.defaultValue.value 默认值，值
	 * @cfg {String} config.elements.defaultValue.text 默认值，文本
	 * @cfg {Array|Function} config.elements.options 针对于固定值选择的输入框控件，需要指定输入框初始化下拉固定值的数组或者函数
	 * @cfg {String} [action] form表单的action属性，一般用于表单提交用	
	 * <pre>
	 * 使用示例：new FormView({config: {elements:[{id:"1233",type:"text",label:"用户名",defaultValue:{value:"",text:""},options:[],enumCode:""}],action:""}});
	 * 
	 * </pre>
	 */
	
	/**
	 * @event onChange 下拉框值改变时候触发的事件
	 * @param {String} id 输入框定义的ID
	 */
});